package basicelement;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import istar.IElement;
import istar.agent.IstarJadeAgent;
import istar.behaviour.AbstractIstarBehaviour;
import istar.impl.AbstractBasicTask;
import istar.impl.TaskDecompositionLink;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;


public class ProcessOrder extends AbstractBasicTask{

	private boolean log = true;
	
	public ProcessOrder() {
		super("ProcessOrder"); 
	}

	@Override
	public Behaviour getBehaviour() {
		return new myBehaviour(this);
	}
	
	private class myBehaviour extends AbstractIstarBehaviour{

		AbstractBasicTask task;
		private int estimatedTime = 100;
		
		public myBehaviour(AbstractBasicTask _task){
			super(_task);
		}
		
		@Override
		public long getEstimatedWaitingTime() {
			return estimatedTime;
		}


		@Override
		public void myAction() {
			
			System.out.println("ProcessOrder executing");

			ACLMessage msg = ((IstarJadeAgent)myAgent).getWorkingMessages().get(getElement().getExecutionNumber());
			try {
				String order = ((ArrayList<String>)msg.getContentObject()).get(0);
				if (recordOrder(order)){
					System.out.println("************** Funcionou! **************");
				}
				else {
					System.out.println("************** Funcionou! **************");
					
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			/*
            IElement main = (IElement)((IstarJadeAgent)myAgent).getKnowledgeElement(this.getElement().getExecutionNumber(), this.getElement().getMain().getId()) ;
            String simulationStep= "";
            // getting quotation parameter
            
            ACLMessage msg = ((IstarJadeAgent)myAgent).getWorkingMessages().get(getElement().getExecutionNumber());
				
			String orderSignal = (String)main.getContent().get(0);
			//String orderSignal = (String)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "Order");
			
			
			
			Integer qttlowStock = (Integer)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStock");
			Integer qtthighStock = (Integer)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStock");
			Double money = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "Money");
			Double strikesGap, fee=new Double(0);
			
			int firstMark = orderSignal.indexOf(";");
			int secondMark = orderSignal.indexOf(";", firstMark);
			int thirdMark = orderSignal.indexOf(";", secondMark);
			String lowStockName = orderSignal.substring(firstMark+1, orderSignal.indexOf("=", firstMark));
			String lowStockAction = orderSignal.substring(orderSignal.indexOf("=", firstMark)+1, secondMark); 
			String highStockName = orderSignal.substring(secondMark+1, orderSignal.indexOf("=", secondMark));
			String highStockAction = orderSignal.substring(orderSignal.indexOf("=", secondMark)+1, thirdMark); 
				
			try {
				Date date = (new SimpleDateFormat(TendencyIndicator.dateFormat)).parse(orderSignal.substring(0,firstMark));

				BufferedReader in = new BufferedReader(new FileReader(((IstarJadeAgent)myAgent).configurationPath));
				String str;
				Double highStrike=new Double(0), lowStrike=new Double(0);
			    while ((str = in.readLine()) != null) {
			        if (str.startsWith("BrokerageFee=")){
			        	fee = new Double(str.substring(13));
			        }
			        if (str.startsWith("LowStrike=")){
			        	lowStrike = new Double(str.substring(10));
			        }
			        if (str.startsWith("HighStrike=")){
			        	highStrike = new Double(str.substring(11));
			        }
			    }
			    strikesGap = highStrike - lowStrike;
			    in.close();
			    
			    String order="";
			    
			    // sell order
			    if (lowStockAction.equals(TendencyIndicator.sell)){
				    order = sellOrder(date, money, qttlowStock, qtthighStock, strikesGap, fee);
			    }
			    
			    recordOrder(order);
			    
			    
			    log(order);
			    System.out.println("Order:" +  order);
			    ((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "Order", orderSignal);
			    Iterator<TaskDecompositionLink> itEnds = getElement().getSupports().iterator();
			    while (itEnds.hasNext()){
			    	IElement end = itEnds.next().getOwner();
			    	end.getContent().clear();
			    	end.getContent().add(orderSignal);
			    }
			    
				ACLMessage reply = msg.createReply();
				msg.setPerformative(ACLMessage.CONFIRM);
	            reply.setContentObject(order);

				myAgent.send(reply);
	            //done = true;

			    
			} catch (Exception e) {
				e.printStackTrace();
			} 
			*/
		}
		
		private boolean recordOrder(String _order){
			boolean result = false;
			try {
				BufferedReader in = new BufferedReader(new FileReader(((IstarJadeAgent)myAgent).configurationPath));
				String str, stockFile=null, moneyFile=null;
			    while ((str = in.readLine()) != null) {
			        if (str.startsWith("StockFile=")){
			        	stockFile = str.substring(10);
			        }
			        if (str.startsWith("MoneyFile=")){
			        	moneyFile = str.substring(10);
			        }

			    }
			    in.close();
			    int firstSeparator=0, secondSeparator=0, thirdSeparator=0;
			    
			    firstSeparator = _order.indexOf(";");
			    secondSeparator = _order.indexOf(";", firstSeparator+1);
			    thirdSeparator = _order.indexOf(";", secondSeparator+1);
			    
			    
			    String time = _order.substring(0,_order.indexOf(";"));
			    
			    int indexQttlow = _order.indexOf("qttlowstock=")+12;
			    String qttlowstock = _order.substring(indexQttlow, _order.indexOf(";", indexQttlow+1));
			    
			    int indexQtthigh = _order.indexOf("qtthighstock=")+13;
			    String qtthighstock = _order.substring(indexQtthigh, _order.indexOf(";", indexQtthigh+1));
			    
			    int indexMoney = _order.indexOf("money=")+6;
			    String money = _order.substring(indexMoney, _order.indexOf(";", indexMoney+1));
			    
			    int indexBlocked = _order.indexOf("blocked=")+8;
			    String blocked = _order.substring(indexBlocked, _order.indexOf(";", indexBlocked+1));
			    
			    int indexPriceLow = _order.indexOf("lowstockprice=")+14;
			    String lowstockprice = _order.substring(indexPriceLow, _order.indexOf(";", indexPriceLow+1));
			    
			    int indexPriceHigh = _order.indexOf("highstockprice=")+15;
			    String highstockprice = _order.substring(indexPriceHigh, _order.indexOf(";", indexPriceHigh+1));
			    
			    int indexPreviousMoney = _order.indexOf("previous-money=")+15;
			    String previous_money = _order.substring(indexPreviousMoney);
			    
		    	String stockLine = time + ";" + qttlowstock + ";" + qtthighstock + ";" +
		    						lowstockprice + ";" + highstockprice ;
		    	
			    String moneyLine = time + ";" + money + ";" + blocked + ";" + previous_money ;  
			    
			    
			    /*
			    BufferedReader stockReader = new BufferedReader(new FileReader(stockFile));
			    String sResult = stockReader.readLine();
			    sResult += "\n" + stockLine;
			    
			    String line;
			    while ((line = stockReader.readLine()) != null) {
			    	sResult += "\n"+ line;
			    }
			    stockReader.close();
			    
			    BufferedWriter stockWriter = new BufferedWriter(new FileWriter(stockFile));
			    stockWriter.write(sResult);
			    stockWriter.close();
			    
			    BufferedReader moneyReader = new BufferedReader(new FileReader(moneyFile));
			    String mResult = moneyReader.readLine();
			    mResult += "\n" + moneyLine;
			    
			    while ((line = moneyReader.readLine()) != null){
			    	mResult += "\n" + line;
			    }
			    moneyReader.close();
			    
			    BufferedWriter moneyWriter = new BufferedWriter(new FileWriter(moneyFile));
			    moneyWriter.write(mResult);
			    moneyWriter.close();
			    */
			    File stockOut = new File (stockFile), moneyOut = new File(moneyFile);

				try {

					FileWriter fwStock = new FileWriter(stockOut, true), fwMoney = new FileWriter(moneyOut, true);
					BufferedWriter bwStock = new BufferedWriter(fwStock), bwMoney = new BufferedWriter(fwMoney);

					bwStock.write(stockLine);
					bwStock.newLine();
					bwStock.flush();
					bwStock.close();
					
					bwMoney.write(moneyLine);
					bwMoney.newLine();
					bwMoney.flush();
					bwMoney.close();

					ACLMessage msg = ((IstarJadeAgent)myAgent).getWorkingMessages().get(getElement().getExecutionNumber());
					
					ACLMessage reply = msg.createReply();
					msg.setPerformative(ACLMessage.INFORM);
		            reply.setContentObject("StockLine=" + stockLine + "\n" + "MoneyLine=" + moneyLine);
		            myAgent.send(reply);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			    
			    result = true;
			    
			} catch (Exception e) {
				e.printStackTrace();
			}
			return result;
		}
		
		private String binarySearchLine(Date _date){
			try {
				boolean found=false;
				String stockPricesFileName = (String)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "StockPricesFile");
				File pricesFile = new File(stockPricesFileName);
				long searchLenght = pricesFile.length(); 
				long initialPos =0;
				long finalPos = pricesFile.length()-1;
				long skipTo = Math.round(searchLenght/2);
				BufferedReader in = new BufferedReader(new FileReader(pricesFile));

				
				String str=null;
				Double stockLowPrice=null, stockHighPrice=null;
				Date lineDate = null;  
				DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm");
				
				System.out.println("Date instant: "+ formatter.format(_date));
				String dateStr;
				while (!found){
					in.skip(skipTo);
					
					str = in.readLine();
					if (str!=null){
						
						try {
							dateStr = str.substring(0, str.indexOf(";"));
							lineDate = (java.util.Date)formatter.parse(dateStr);
						} catch (Exception e) {
							str = in.readLine();
							dateStr = str.substring(0, str.indexOf(";"));
							lineDate = (java.util.Date)formatter.parse(dateStr);
						} 
						

						//int comp = lineDate.compareTo(_date);
						//if (comp==0){
						if (lineDate.equals(_date)){
				        	stockLowPrice = getLowStockPrice(str);
				        	stockHighPrice = getHighStockPrice(str);
				        	found=true;
							in.close();
							
						}
						else if (lineDate.after(_date)){
							finalPos = skipTo;
							searchLenght = Math.round((finalPos-initialPos));
							skipTo = initialPos + Math.round(searchLenght/2);
							in.close();
							in = new BufferedReader(new FileReader(pricesFile));
						}
						else if (lineDate.before(_date)){
							initialPos = skipTo;
							searchLenght = Math.round((finalPos-initialPos));
							//finalPos = initialPos + searchLenght;
							skipTo = initialPos + Math.round(searchLenght/2);
							in.close();
							in = new BufferedReader(new FileReader(pricesFile));
						}

					}
				}

				if (str==null)
					System.out.println(".,.,.,.,.,.,.,. nao funciona -=-==--=-=-=");;

				return str;
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		private Double getLowStockPrice(String line){
			int firstMark = line.indexOf(";");
			int secondMark = line.indexOf(";", firstMark+1);
			String lowStr = line.substring(firstMark+1, secondMark);
			return new Double(lowStr);
			
		}
		
		private Double getHighStockPrice(String line){
			int firstMark = line.indexOf(";");
			int secondMark = line.indexOf(";", firstMark+1);
			int thirdMark =  line.indexOf(";", secondMark+1);
			int fourthMark =  line.indexOf(";", thirdMark+1);
			String highStr = line.substring(thirdMark+1, fourthMark);
			return new Double(highStr);
		}

		@Override
		public int myOnEnd() {
			// TODO Auto-generated method stub
			return 1;
		}

		@Override
		public boolean done() {
			return true;
		}
	}
}
